package commander;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import core.*;
import repository.Repository;


public class CLI {

	/**
	 * Command 'jit init'
	 *
	 * @param args
	 * @throws IOException
	 */
	public static void jitInit(String[] args) throws IOException {
		String path;
		if (args.length <= 2) { //get default working path
			path = new File(".").getCanonicalPath();
			JitInit.init(path);
		} else if (args[2].equals("-help")) { //see help
			System.out.println("usage: jit init [<path>] [-help]\r\n" +
					"\r\n" +
					"jit init [<path>]:	Create an empty jit repository or reinitialize an existing one in the path or your default working directory.");
		} else {
			path = args[2];
			if (!new File(path).isDirectory()) { //if the working path input is illegal
				System.out.println(path + " is not a legal directory. Please init your repository again. See 'jit init -help'.");
			} else {
				JitInit.init(path);
			}
		}
	}

	public static void jitHash(String[] args) throws IOException {
		String worktreeDir = Repository.getWorkTree();
		String path = args[2];
		JitHash.hash(worktreeDir +File.separator+ path);
	}

	public static void jitAdd(String[] args) throws Exception {
		if (args.length < 2) {
			System.out.println("Please add file.");
		} else {
			String worktreeDir = Repository.getWorkTree();
			for (int i = 2; i < args.length; i++) {
				File file = new File(worktreeDir + File.separator + args[i]);
				if (!file.exists())
					System.out.println("fatal: pathspec '"+ args[i]+ "' did not match any files");
				else {
					JitAdd.add(file);
					System.out.println("File "+ args[i] + " staged successfully");
				}
			}
		}
	}

	public static void jitRemove(String[] args) throws Exception {
		if (args.length < 2) {
			System.out.println("Please enter file name.");
		} else if (args[2].equals("--cached")) {
			for (int i = 3; i < args.length; i++) {
				JitRm.removeCached(args[i]);
			}
		} else {
			for (int i = 2; i < args.length; i++) {
				JitRm.remove(args[i]);
			}
		}
	}

	public static void jitCommit(String[] args) throws Exception{
		if (args.length==4 &&args[2].equals("-m")){
			JitCommit.commit(args[3]);
		}
		else
			System.out.println("Please enter the commit message for your commit.");
	}

	public static void jitBranch(String[] args) throws Exception{
		if(args.length == 2)
			JitBranch.printBranch();
		else if(args.length == 3)
			JitBranch.branch(args[2]);
		else if (args.length == 4 && args[2].equals("-d"))
			JitBranch.deleteBranch(args[3]);
		else
			System.out.println("See jit help.");
	}

	public static void jitCheckout(String[] args) throws Exception{
		if(args.length==3)
			JitCheckout.checkout(args[2]);
		else if(args.length==4 &&args[2].equals("-b"))
			JitCheckout.checkoutBranch(args[3]);
		else
			System.out.println("See jit help.");
	}

	public static void jitLog(String[] args) throws Exception{
		if (args.length==2)
			JitLog.log();
		else
			System.out.println("See jit help.");
	}

	public static void jitReset(String[] args)throws Exception{
		if (args.length==4){
			switch (args[2]) {
				case "--soft" -> JitReset.reset("soft", args[3]);
				case "--mixed" -> JitReset.reset("mixed", args[3]);
				case "--hard" -> JitReset.reset("hard", args[3]);
				default -> System.out.println("See jit help.");
			}
		}
		else
			System.out.println("See jit help.");
	}

	public static void jitLsFiles(String[] args)throws IOException{
		if (args.length ==2)
			JitLsFiles.lsFiles();
		else
			System.out.println("See jit help.");
	}

	public static void jitCatFile(String[] args) throws Exception{
		if (args.length == 4) {
			switch (args[2]) {
				case "blob" -> JitCatFile.catFileBlob(args[3]);
				case "tree" -> JitCatFile.catFileTree(args[3]);
				case "commit" -> JitCatFile.catFileCommit(args[3]);
				default -> System.out.println("Please enter type of object(blob tree commit)");
			}
		}
		else
			System.out.println("See jit help");
	}

	public static void jitDiff(String[] args) throws Exception{
		if (args.length == 2){
			JitDiff.diff();
		}
	}

	/**
	 * Command 'jit help'.
	 */
	public static void jitHelp() {
		System.out.println("usage: jit [--version] [--help] [-C <path>] [-c name=value]\r\n" +
				"           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\r\n" +
				"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\r\n" +
				"           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\r\n" +
				"           <command> [<args>]\r\n" +
				"\r\n" +
				"These are common Jit commands used in various situations:\r\n" +
				"\r\n" +
				"start a working area\r\n" +
				"   init       Create an empty Jit repository or reinitialize an existing one\r\n" +
				"\r\n" +
				"work on the current change\r\n" +
				"   add        Add file contents to the index\r\n" +
				"   reset      Reset current HEAD to the specified state\r\n" +
				"   rm         Remove files from the working tree and from the index\r\n" +
				"\r\n" +
				"examine the history and state\r\n" +
				"   log        Show commit logs\r\n" +
				"   status     Show the working tree status\r\n" +
				"\r\n" +
				"grow, mark and tweak your common history\r\n" +
				"   branch     List, create, or delete branches\r\n" +
				"   checkout   Switch branches or restore working tree files\r\n" +
				"   commit     Record changes to the repository\r\n" +
				"   diff       Show changes between commits, commit and working tree, etc\r\n" +
				"   merge      Join two or more development histories together\r\n" +
				"\r\n" +
				"'jit help -a' and 'jit help -g' list available subcommands and some\r\n" +
				"concept guides. See 'jit help <command>' or 'jit help <concept>'\r\n" +
				"to read about a specific subcommand or concept.");
	}

	public static void run(String[] args) throws Exception {
		if (args.length <= 1 || args[1].equals("help")) {
			jitHelp();
		} else if (!args[0].equals("jit")) {
			System.out.println(args[0] + ": command not found");
		} else {
			switch (args[1]) {
				case "init" -> jitInit(args);
				case "hash" -> jitHash(args);
				case "add" -> jitAdd(args);
				case "rm" -> jitRemove(args);
				case "commit" -> jitCommit(args);
				case "branch" -> jitBranch(args);
				case "checkout" -> jitCheckout(args);
				case "log" -> jitLog(args);
				case "reset" -> jitReset(args);
				case "ls-files" ->jitLsFiles(args);
				case "cat-file" ->jitCatFile(args);
				case "diff" -> jitDiff(args);
				default -> System.out.println("jit: " + args[1] + " is not a jit command. See 'jit help'.");
			}
		}
	}

	public static void main(String[] args) throws Exception{
		Scanner scanner = new Scanner(System.in);
		String line  = scanner.nextLine();
		String[] arg = line.split(" ");
		while (!arg[0].equals("end")){
			run(arg);
			arg = scanner.nextLine().split(" ");
		}
	}
}
